﻿using Client.Framework;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class CheckAssetTools
{
    static CheckAssetTools checkAsset = new CheckAssetTools();

    [MenuItem("Tools/NormalizeTransform")]
    public static void NormalizeAssetTransform()
    {
        var assetGuids = AssetDatabase.FindAssets("t:Prefab");
        for (int i = 0; i < assetGuids.Length; i++)
        {
            var assetPath = AssetDatabase.GUIDToAssetPath(assetGuids[i]);
            var obj = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);

            if (obj != null)
            {
                checkAsset.NormalizeComponent(obj.transform);
                checkAsset.NormalizeTransform(obj.transform);
                PrefabUtility.SavePrefabAsset(obj, out bool success);
            }
            EditorUtility.DisplayProgressBar("规整资源Transform", assetPath, (i + 1f) / assetGuids.Length);
        }

        Debug.Log($"总共查找到:{assetGuids.Length}个资源预设");
        EditorUtility.ClearProgressBar(); AssetDatabase.Refresh();
    }

    [MenuItem("GameObject/Tools/NormalizeTransform")]
    public static void NormalizeGoTransform()
    {
        var selectObjs = Selection.gameObjects;
        for (int i = 0; i < selectObjs.Length; i++)
        {
            var path = AssetDatabase.GetAssetPath(selectObjs[i]);
            checkAsset.NormalizeComponent(selectObjs[i].transform);
            checkAsset.NormalizeTransform(selectObjs[i].transform);

            EditorUtility.SetDirty(selectObjs[i]);
            EditorUtility.DisplayProgressBar("规整资源Transform", path, (i + 1f) / selectObjs.Length);
        }
        EditorUtility.ClearProgressBar(); AssetDatabase.Refresh();
    }

    void NormalizeTransform(Transform tf)
    {
        for (int i = 0; i < tf.childCount; i++)
        {
            var transform = tf.GetChild(i);
            NormalizeComponent(transform);
            NormalizeTransform(transform);
        }
    }

    void NormalizeComponent(Transform tf)
    {
        tf.localScale = NormalizeVector(tf.localScale, 2);
        //tf.localEulerAngles = NormalizeVector(tf.localEulerAngles, 0);
        tf.localPosition = NormalizeVector(tf.localPosition, 2);

        if (tf is RectTransform)
        {
            var rtf = tf as RectTransform;
            rtf.pivot = NormalizeVector(rtf.pivot);
            rtf.anchorMin = NormalizeVector(rtf.anchorMin);
            rtf.anchorMax = NormalizeVector(rtf.anchorMax);

            if (rtf.anchorMin.x > rtf.anchorMax.x)
            {
                Debug.LogWarning(tf.BuildTfPath(), tf);
            }
            if (rtf.anchorMin.y > rtf.anchorMax.y)
            {
                Debug.LogWarning(tf.BuildTfPath(), tf);
            }

            rtf.sizeDelta = NormalizeVector(rtf.sizeDelta, 0);
            rtf.anchoredPosition = NormalizeVector(rtf.anchoredPosition, 0);
        }
        NormalizeCollider(tf); NormalizeLayoutElement(tf);
    }

    void NormalizeCollider(Transform tf)
    {
        var collider = tf.GetComponent<Collider>();
        if (collider == null) { return; }

        if (collider is BoxCollider)
        {
            var box = collider as BoxCollider;
            box.center = NormalizeVector(box.center, 2);
            box.size = NormalizeVector(box.size, 2);
        }
        else if (collider is SphereCollider)
        {
            var sphere = collider as SphereCollider;
            sphere.center = NormalizeVector(sphere.center, 2);
        }
        else if (collider is CapsuleCollider)
        {
            var capsule = collider as CapsuleCollider;
            capsule.center = NormalizeVector(capsule.center, 2);
        }
    }

    void NormalizeLayoutElement(Transform tf)
    {
        var element = tf.GetComponent<LayoutElement>();
        if (element != null)
        {
            element.minWidth = Mathf.RoundToInt(element.minWidth);
            element.minHeight = Mathf.RoundToInt(element.minHeight);
            element.preferredWidth = Mathf.RoundToInt(element.preferredWidth);
            element.preferredHeight = Mathf.RoundToInt(element.preferredHeight);
            element.flexibleWidth = Mathf.RoundToInt(element.flexibleWidth);
            element.flexibleHeight = Mathf.RoundToInt(element.flexibleHeight);
        }

        var layoutGroup = tf.GetComponent<LayoutGroup>();
        if (layoutGroup == null) { return; }

        if (layoutGroup is GridLayoutGroup)
        {
            var grid = layoutGroup as GridLayoutGroup;
            grid.cellSize = NormalizeVector(grid.cellSize, 0);
            grid.spacing = NormalizeVector(grid.spacing, 0);
        }
        else if (layoutGroup is HorizontalOrVerticalLayoutGroup)
        {
            var hvLayoutGroup = layoutGroup as HorizontalOrVerticalLayoutGroup;
            hvLayoutGroup.spacing = Mathf.RoundToInt(hvLayoutGroup.spacing);
        }

        layoutGroup.padding.left = Mathf.RoundToInt(layoutGroup.padding.left);
        layoutGroup.padding.right = Mathf.RoundToInt(layoutGroup.padding.right);
        layoutGroup.padding.top = Mathf.RoundToInt(layoutGroup.padding.top);
        layoutGroup.padding.bottom = Mathf.RoundToInt(layoutGroup.padding.bottom);
    }

    Vector3 NormalizeVector(Vector3 vector, int num)
    {
        float units = Mathf.Pow(10, num);
        vector.x = Mathf.RoundToInt(vector.x * units) / units;
        vector.y = Mathf.RoundToInt(vector.y * units) / units;
        vector.z = Mathf.RoundToInt(vector.z * units) / units;
        return new Vector3(vector.x, vector.y, vector.z);
    }

    Vector2 NormalizeVector(Vector2 vector)
    {
        vector.x = Mathf.Clamp(vector.x, 0, 1);
        vector.y = Mathf.Clamp(vector.y, 0, 1);
        float x = Mathf.RoundToInt(vector.x * 2);
        float y = Mathf.RoundToInt(vector.y * 2);
        return new Vector2(x / 2, y / 2);
    }
}